package ar.uade.distribuidas.tpo.dao;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.joda.time.LocalDate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import ar.uade.distribuidas.tpo.base.dominiodto.EstadoOC;
import ar.uade.distribuidas.tpo.base.dominiodto.EstadoRemito;
import ar.uade.distribuidas.tpo.base.dominiodto.ItemRemitoCPEDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.OrdenDeCompraDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.ProveedorDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.RemitoCPEDTO;
import ar.uade.distribuidas.tpo.base.dominiodto.RodamientoDTO;
import ar.uade.distribuidas.tpo.base.remoto.IGestionOC;
import ar.uade.distribuidas.tpo.base.remoto.IGestionProveedor;
import ar.uade.distribuidas.tpo.base.remoto.IGestionRodamientos;
import ar.uade.distribuidas.tpo.base.utils.FormatUtils;


public class RemitoCPEXmlDAO {
	private static RemitoCPEXmlDAO instancia;
	//private static String ARCHIVO = "remitocpe.xml";
	private Document doc;
	
	
	public static RemitoCPEXmlDAO getInstancia(String nombreArch) {
		if(instancia == null){
			instancia = new RemitoCPEXmlDAO();
			instancia.createDocument(nombreArch);
		}
		return instancia;
	}


	private void createDocument(String nombreArchivo) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder;
		try {
			builder = factory.newDocumentBuilder();
			doc = builder.parse(nombreArchivo+".xml");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	private RemitoCPEXmlDAO() {
		super();
		
	}
	
	
	public  Set<RemitoCPEDTO> recuperarRemitoCPEDTO(){
		Set<RemitoCPEDTO> rcpe = new HashSet<RemitoCPEDTO>();
		NodeList nodos = doc.getElementsByTagName("Remito");
		for(int i = 0; i < nodos.getLength(); i++){
			if(nodos.item(i).hasChildNodes()){
				rcpe.add(mapStock((Element)nodos.item(i)));
			}
		}
		return rcpe;
	}
	
	private RemitoCPEDTO mapStock(Element eleRemitoCpe){
		
		RemitoCPEDTO rcpe = new RemitoCPEDTO();

		try{
			rcpe.setEstado(EstadoRemito.NUEVO);
			DateFormat df = new SimpleDateFormat(FormatUtils.DATE_PATTERN);
			try{
			rcpe.setFecha(df.parse(eleRemitoCpe.getAttribute("Emision")));
			}catch(Exception e){
				rcpe.setFecha(null);
			}
			
			Long cuil = ((Long.parseLong(eleRemitoCpe.getElementsByTagName("Cuil").item(0).getTextContent())));
			//prov.setNombre(elemProv.getAttribute("RazonSocial")); No hace falta ya que sacamos el proveedor de la DB
		
			IGestionProveedor gestion;
			ProveedorDTO pr = null;
			try {
				gestion = (IGestionProveedor) Naming.lookup("GestionCliente");
				pr = gestion.getProveedor(cuil);
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NotBoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			
			
			rcpe.setProveedor(pr);
						
			
			Element referencia = (Element)eleRemitoCpe.getElementsByTagName("Referencia").item(0);
			
			NodeList ordencompras = referencia.getElementsByTagName("OrdenCompra");
			for(int i = 0; i<ordencompras.getLength(); i++){
				
				if (ordencompras.item(i).getNodeType() == Node.ELEMENT_NODE) {
				Element c = (Element) ordencompras.item(i);
				int numero = Integer.parseInt(c.getElementsByTagName("Numero").item(0).getTextContent());
				OrdenDeCompraDTO ordenComp = null; //new GestionOC().getOC(Integer.valueOf(getValue("Numero", c)));
						
						
						IGestionOC gestionOrdenComp;
						try {
							gestionOrdenComp = (IGestionOC) Naming.lookup("GestionOrdenCompra");
							ordenComp = gestionOrdenComp.getOrdenCompra(numero);
						} catch (MalformedURLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (RemoteException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (NotBoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} 
				
				Element rodamiento = (Element)eleRemitoCpe.getElementsByTagName("Rodamientos").item(0);
				NodeList items = rodamiento.getElementsByTagName("Item");
				List<ItemRemitoCPEDTO> itemsRem = new ArrayList<ItemRemitoCPEDTO>();
				
				for (int j = 0; j < items.getLength(); j++) {
					Node item = items.item(j);
	
					if (item.getNodeType() == Node.ELEMENT_NODE) {
						Element it = (Element) item;
						
						
							RodamientoDTO rod= new RodamientoDTO(Long.parseLong(it.getAttribute("serie")), getValue("Sufijo", it), getValue("Marca", it), getValue("Origen", it));
						
							IGestionRodamientos gestionRod = null;
							
							try {
								
								gestionRod = (IGestionRodamientos) Naming.lookup("GestionRodamientos");
								
								if(gestionRod.existeRodamiento(rod)){
									ItemRemitoCPEDTO icpe = null;
									icpe = new ItemRemitoCPEDTO();
									icpe.setCantidad((Integer.valueOf(getValue("Cantidad", it))));
									icpe.setRodamiento(rod);
									icpe.setOc(ordenComp);
									itemsRem.add(icpe);
									
								}
								
							} catch (RemoteException e) {
								e.printStackTrace();
							} catch (MalformedURLException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							} catch (NotBoundException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
												
	
					}
	
				}
				rcpe.setItemOC(itemsRem);
			}
		}
		}catch (Exception e){
			e.printStackTrace();
		}
		return rcpe;
	}

	
	private static String getValue(String tag, Element element) {
		NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();
		Node node = (Node) nodes.item(0);
		if (node!=null) {
			return node.getNodeValue();
		}
		return "";
	}
}